from cy_query.db import models, DEFAULT_DB_ALIAS
from cy_query.db.models import query
from cy_query.db.models.inspectdb import Inspectdb
from cy_query.utils.cache import GlobalCache
from cy_query.apps import apps
import os


def QuerySet(table_name, using_db=DEFAULT_DB_ALIAS,save_table=False) -> query.QuerySet:
    module = os.environ.get('CYQUERY_SETTINGS_MODULE')
    module_file = os.environ.get('CYQUERY_MODELS_FILE')
    model_name = Inspectdb().normalize_table_name(table_name) + using_db.title()
    class Meta:
        db_table = table_name
        app_label = 'base'
        managed = False

    options = {
        'database': using_db,
        'include_partitions': True,
        'include_views': True,
        'table': [table_name],
    }
    inspection = Inspectdb().handle_inspection(options)
    attrs = {
        '__module__': 'base.models',
        'Meta': Meta,
        'objects': models.Manager(),
    }
    attrs.update(**inspection['fields'])
    try:
        model_class = apps.get_model('base', model_name)
        apps.delete_model('base',model_class)
    except LookupError:
        pass
    model_class = type(model_name, (models.Model,), attrs)
    model = model_class.objects.using(using_db).values()
    if save_table:
        if not module_file:
            modules,file = module.rsplit('.',1)
            models_file = os.path.join(modules,'models')
        models_file += '.py'
        data = ["# This is an auto-generated cy_query model module.\n",
                "# You'll have to do the following manually to clean this up:\n",
                "#   * Rearrange models' order\n",
                "#   * Make sure each model has one field with primary_key=True\n",
                "#   * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior\n",
                "#   * Remove `managed = False` lines if you wish to allow cy_query to create, modify, and delete the table\n",
                "# Feel free to rename the models, but don't rename db_table values or field names.\n",
                "from cy_query import models\n","\n\n"]
        if os.path.exists(models_file):
            with open(models_file,'r',encoding='utf-8') as fp:
                data = fp.readlines()
                data.append('\n\n')
                if "class %s(models.Model):\n" % model_name in data:
                    return model
        # 将新的model写入文件
        data.append("class %s(models.Model):\n" % model_name)
        for k,v in inspection['fields'].items():
            if v.primary_key:
                data.append("    %s = models.%s(primary_key=True)\n"% (k,v.__class__.__name__))
            elif v.__class__.__name__ == 'CharField':
                data.append("    %s = models.CharField(max_length=%s, null=True, blank=True)\n" % (k,v.max_length))
            else:
                data.append("    %s = models.%s(null=True, blank=True)\n"% (k,v.__class__.__name__))
        data.append('\n    class Meta:\n')
        data.append("        managed = False\n")
        data.append("        db_table = '%s'\n" % table_name)
        with open(models_file, 'w', encoding='utf-8') as fp:
            fp.writelines(data)
    return model
